package com.uduemc.biso.node.web.api.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateException;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.uduemc.biso.core.extities.center.Host;
import com.uduemc.biso.core.extities.node.custom.LoginNode;
import com.uduemc.biso.core.utils.CryptoJava;
import com.uduemc.biso.core.utils.JsonResult;
import com.uduemc.biso.core.utils.RestResult;
import com.uduemc.biso.core.utils.ResultUtil;
import com.uduemc.biso.node.core.common.dto.*;
import com.uduemc.biso.node.core.common.dto.pdtable.InsertPdtableListData;
import com.uduemc.biso.node.core.common.dto.pdtable.PdtableTitleItem;
import com.uduemc.biso.node.core.common.entities.common.RepertoryImgTagConfig;
import com.uduemc.biso.node.core.common.feign.CPdtableFeign;
import com.uduemc.biso.node.core.common.sysconfig.PdtableSysConfig;
import com.uduemc.biso.node.core.dto.FeignSPdtableByIds;
import com.uduemc.biso.node.core.dto.FeignSPdtableTitleInsertAfterById;
import com.uduemc.biso.node.core.dto.FeignSPdtableTitleResetOrdernum;
import com.uduemc.biso.node.core.dto.FeignSystemTotal;
import com.uduemc.biso.node.core.entities.*;
import com.uduemc.biso.node.core.entities.custom.CategoryQuote;
import com.uduemc.biso.node.core.entities.custom.PdtableList;
import com.uduemc.biso.node.core.entities.custom.PdtableOne;
import com.uduemc.biso.node.core.entities.custom.pdtable.PdtableItem;
import com.uduemc.biso.node.core.feign.SPdtableFeign;
import com.uduemc.biso.node.core.feign.SPdtableTitleFeign;
import com.uduemc.biso.node.core.property.GlobalProperties;
import com.uduemc.biso.node.core.utils.RestResultUtil;
import com.uduemc.biso.node.core.utils.SitePathUtil;
import com.uduemc.biso.node.core.utils.SystemConfigUtil;
import com.uduemc.biso.node.web.api.component.RequestHolder;
import com.uduemc.biso.node.web.api.dto.RequestItemSeo;
import com.uduemc.biso.node.web.api.dto.item.ItemCustomLink;
import com.uduemc.biso.node.web.api.dto.pdtable.RequestPdtableList;
import com.uduemc.biso.node.web.api.dto.pdtable.RequestPdtableSave;
import com.uduemc.biso.node.web.api.dto.pdtable.RequestPdtableTitleSave;
import com.uduemc.biso.node.web.api.service.*;
import com.uduemc.biso.node.web.api.service.fegin.SPdtableTitleService;
import com.uduemc.biso.node.web.api.service.hostsetup.HSSystemDataNumService;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PdtableServiceImpl implements PdtableService {

    @Resource
    private RequestHolder requestHolder;

    @Resource
    private SPdtableFeign sPdtableFeign;

    @Resource
    private SPdtableTitleFeign sPdtableTitleFeign;

    @Resource
    private SPdtableTitleService sPdtableTitleServiceImpl;

    @Resource
    private CPdtableFeign cPdtableFeign;

    @Resource
    private SystemService systemServiceImpl;

    @Resource
    private CategoryService categoryServiceImpl;

    @Resource
    private SystemItemCustomLinkService systemItemCustomLinkServiceImpl;

    @Resource
    private HSSystemDataNumService hSSystemDataNumServiceImpl;

    @Resource
    private RepertoryService repertoryServiceImpl;

    @Resource
    private GlobalProperties globalProperties;

    @Resource
    private ObjectMapper objectMapper;

    @Resource
    private LoginService loginServiceImpl;

    @Override
    public SPdtableTitle insertSPdtableTitle(RequestPdtableTitleSave pdtableTitleSave) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        SPdtableTitle makeSPdtableTitle = pdtableTitleSave.makeSPdtableTitle(hostId, siteId);
        makeSPdtableTitle.setConf("");

        FeignSPdtableTitleInsertAfterById sPdtableTitleInsertAfterById = new FeignSPdtableTitleInsertAfterById();
        sPdtableTitleInsertAfterById.setData(makeSPdtableTitle).setAfterId(pdtableTitleSave.getAfterId());

        RestResult restResult = sPdtableTitleFeign.insertAfterById(sPdtableTitleInsertAfterById);
        SPdtableTitle data = RestResultUtil.data(restResult, SPdtableTitle.class);

        return data;
    }

    @Override
    public SPdtableTitle updateSPdtableTitle(SPdtableTitle sPdtableTitle) throws IOException {
        RestResult restResult = sPdtableTitleFeign.updateByPrimaryKey(sPdtableTitle);
        SPdtableTitle data = RestResultUtil.data(restResult, SPdtableTitle.class);
        return data;
    }

    @Override
    public SPdtableTitle findSPdtableTitle(long id) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        return sPdtableTitleServiceImpl.findByHostSiteIdAndId(id, hostId, siteId);
    }

    @Override
    public SPdtableTitle findSPdtableTitle(long id, long systemId) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();
        return sPdtableTitleServiceImpl.findByHostSiteSystemIdAndId(id, hostId, siteId, systemId);
    }

    @Override
    public List<SPdtableTitle> findSPdtableTitleByHostSiteSystemId(long systemId) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        return findSPdtableTitleByHostSiteSystemId(hostId, siteId, systemId);
    }

    @Override
    public List<SPdtableTitle> findSPdtableTitleByHostSiteSystemId(long hostId, long siteId, long systemId) throws IOException {
        return sPdtableTitleServiceImpl.findByHostSiteSystemId(hostId, siteId, systemId);
    }

    @Override
    public boolean resetSPdtableTitleOrdernum(List<Long> ids, long systemId) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        FeignSPdtableTitleResetOrdernum sPdtableTitleResetOrdernum = new FeignSPdtableTitleResetOrdernum();
        sPdtableTitleResetOrdernum.setIds(ids).setHostId(hostId).setSiteId(siteId).setSystemId(systemId);

        RestResult restResult = sPdtableTitleFeign.resetOrdernum(sPdtableTitleResetOrdernum);
        Boolean data = RestResultUtil.data(restResult, Boolean.class);
        return data != null && data;
    }

    @Override
    public int totalSPdtableTitleByHostSiteSystemId(long systemId) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();
        RestResult restResult = sPdtableTitleFeign.totalByHostSiteSystemId(hostId, siteId, systemId);
        Integer data = RestResultUtil.data(restResult, Integer.class);
        return data == null ? 0 : data;
    }

    @Override
    public int totalSPdtableByHostSiteSystemId(long systemId) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        RestResult restResult = sPdtableFeign.totalByHostSiteSystemId(hostId, siteId, systemId);
        Integer data = RestResultUtil.data(restResult, Integer.class);
        return data == null ? 0 : data;
    }

    @Override
    public int totalSPdtableByHostId(long hostId) throws IOException {
        RestResult restResult = sPdtableFeign.totalByHostId(hostId);
        Integer data = RestResultUtil.data(restResult, Integer.class);
        return data == null ? 0 : data;
    }

    @Override
    public int totalSPdtableByFeignSystemTotal(long hostId, long systemId) throws IOException {
        FeignSystemTotal feignSystemTotal = new FeignSystemTotal();
        feignSystemTotal.setHostId(hostId).setSystemId(systemId);
        RestResult restResult = sPdtableFeign.totalByFeignSystemTotal(feignSystemTotal);
        Integer data = ResultUtil.data(restResult, Integer.class);
        if (data == null) {
            return 0;
        }
        return data;
    }

    @Override
    public SPdtableTitle deleteSPdtableTitle(long id) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        RestResult restResult = cPdtableFeign.deleteSPdtableTitle(id, hostId, siteId);
        SPdtableTitle data = RestResultUtil.data(restResult, SPdtableTitle.class);

        return data;
    }

    @Override
    public SPdtable findSPdtable(long id) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        RestResult restResult = sPdtableFeign.findByHostSiteIdAndId(id, hostId, siteId);
        SPdtable data = RestResultUtil.data(restResult, SPdtable.class);

        return data;
    }

    @Override
    public SPdtable findSPdtable(long id, long systemId) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        return findSPdtable(id, hostId, siteId, systemId);
    }

    @Override
    public SPdtable findSPdtable(long id, long hostId, long siteId, long systemId) throws IOException {

        RestResult restResult = sPdtableFeign.findByHostSiteSystemIdAndId(id, hostId, siteId, systemId);
        SPdtable data = RestResultUtil.data(restResult, SPdtable.class);

        return data;
    }

    @Override
    public List<SPdtable> findSPdtableByIds(long systemId, List<Long> ids) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        FeignSPdtableByIds feignSPdtableByIds = new FeignSPdtableByIds();
        feignSPdtableByIds.setHostId(hostId).setSiteId(siteId).setSystemId(systemId).setIds(ids);
        RestResult restResult = sPdtableFeign.findByHostSiteSystemIdAndIds(feignSPdtableByIds);

        @SuppressWarnings("unchecked")
        List<SPdtable> list = (ArrayList<SPdtable>) RestResultUtil.data(restResult, new TypeReference<ArrayList<SPdtable>>() {
        });

        return list;
    }

    @Override
    public SPdtable updateSPdtable(SPdtable sPdtable) throws IOException {
        RestResult restResult = sPdtableFeign.updateByPrimaryKey(sPdtable);
        SPdtable data = RestResultUtil.data(restResult, SPdtable.class);

        return data;
    }

    @Override
    public PdtableList pdtableList(RequestPdtableList pdtableList) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        long systemId = pdtableList.getSystemId();
        short status = pdtableList.getStatus();
        String keyword = pdtableList.getKeyword();
        List<Long> categoryIds = pdtableList.getCategoryIds();
        keyword = keyword != null ? StrUtil.trim(keyword) : "";
        keyword = StrUtil.isBlank(keyword) ? "" : keyword;
        int page = pdtableList.getPage();
        int size = pdtableList.getSize();

        SSystem sSystem = systemServiceImpl.getInfoById(systemId, hostId, siteId);
        if (sSystem == null) {
            return null;
        }
        PdtableSysConfig pdtableSysConfig = SystemConfigUtil.pdtableSysConfig(sSystem);

        int orderby = pdtableSysConfig.getList().getOrderby();

        FeignFindPdtableList findPdtableList = new FeignFindPdtableList();
        findPdtableList.setHostId(hostId).setSiteId(siteId).setSystemId(systemId).setCategoryIds(categoryIds).setStatus(status).setRefuse((short) 0)
                .setKeyword(keyword).setOrderBy(orderby).setPage(page).setSize(size);
        RestResult restResult = cPdtableFeign.findPdtableList(findPdtableList);
        PdtableList data = RestResultUtil.data(restResult, PdtableList.class);

        return data;
    }

    @Override
    public PdtableList refusePdtableList(RequestPdtableList pdtableList) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        long systemId = pdtableList.getSystemId();
        short status = pdtableList.getStatus();
        String keyword = pdtableList.getKeyword();
        List<Long> categoryIds = pdtableList.getCategoryIds();
        keyword = keyword != null ? StrUtil.trim(keyword) : "";
        keyword = StrUtil.isBlank(keyword) ? "" : keyword;
        int page = pdtableList.getPage();
        int size = pdtableList.getSize();

        SSystem sSystem = systemServiceImpl.getInfoById(systemId, hostId, siteId);
        if (sSystem == null) {
            return null;
        }
        PdtableSysConfig pdtableSysConfig = SystemConfigUtil.pdtableSysConfig(sSystem);

        int orderby = pdtableSysConfig.getList().getOrderby();

        FeignFindPdtableList findPdtableList = new FeignFindPdtableList();
        findPdtableList.setHostId(hostId).setSiteId(siteId).setSystemId(systemId).setCategoryIds(categoryIds).setStatus(status).setRefuse((short) 1)
                .setKeyword(keyword).setOrderBy(orderby).setPage(page).setSize(size);
        RestResult restResult = cPdtableFeign.findPdtableList(findPdtableList);
        PdtableList data = RestResultUtil.data(restResult, PdtableList.class);

        return data;
    }

    @Override
    public PdtableOne pdtableOne(long id) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        RestResult restResult = cPdtableFeign.findPdtableOne(id, hostId, siteId);
        PdtableOne data = RestResultUtil.data(restResult, PdtableOne.class);

        if (data != null) {
            makeCustomLink(data);
        }

        return data;
    }

    @Override
    public PdtableOne insertPdtable(RequestPdtableSave pdtableSave) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        long systemId = pdtableSave.getSystemId();
        short status = pdtableSave.getStatus();
        String content = pdtableSave.getContent();
        Date releasedAt = pdtableSave.getReleasedAt();
        List<PdtableTitleItem> titleItem = pdtableSave.getTitleItem();
        long imageRepertoryId = pdtableSave.getImageRepertoryId();
        RepertoryImgTagConfig repertoryImgTagConfig = pdtableSave.getImageRepertoryConfig();
        String imageRepertoryConfig = objectMapper.writeValueAsString(repertoryImgTagConfig);
        long fileRepertoryId = pdtableSave.getFileRepertoryId();
        String fileRepertoryConfig = pdtableSave.getFileRepertoryConfig();

        List<Long> categoryIds = pdtableSave.getCategoryIds();
        RequestItemSeo seo = pdtableSave.getSeo();
        SSeoItem sSeoItem = new SSeoItem();
        sSeoItem.setHostId(hostId).setSiteId(siteId).setSystemId(siteId).setItemId(-1L).setTitle(seo.getTitle()).setKeywords(seo.getKeywords())
                .setDescription(seo.getDescription());

        FeignInsertPdtable insertPdtable = new FeignInsertPdtable();
        insertPdtable.setHostId(hostId).setSiteId(siteId).setSystemId(systemId).setStatus(status).setRefuse((short) 0).setTop((short) 0).setOrderNum(1)
                .setContent(content).setReleasedAt(releasedAt).setTitleItem(titleItem).setImageRepertoryId(imageRepertoryId)
                .setImageRepertoryConfig(imageRepertoryConfig).setFileRepertoryId(fileRepertoryId).setFileRepertoryConfig(fileRepertoryConfig)
                .setCategoryIds(categoryIds).setSeo(sSeoItem);

        RestResult restResult = cPdtableFeign.insertPdtable(insertPdtable);
        PdtableOne data = RestResultUtil.data(restResult, PdtableOne.class);

        if (data != null) {
            ItemCustomLink customLink = pdtableSave.getItemCustomLink();
            if (customLink != null) {
                makeCustomLink(data, customLink);
            } else {
                // 删除动作
                systemItemCustomLinkServiceImpl.deleteByHostSiteSystemItemId(hostId, siteId, systemId, data.getOne().getData().getId());
            }

            if (data.getOne() != null && data.getOne().getData() != null) {
                List<CategoryQuote> listCategoryQuote = data.getOne().getListCategoryQuote();
                List<Long> categoryIdsCategoryQuote = CollUtil.isEmpty(listCategoryQuote) ? null : listCategoryQuote.stream().map(item -> item.getSCategories().getId()).collect(Collectors.toList());
                LoginNode loginNode = requestHolder.getCurrentLoginNode();
                loginNode.saveSystemCategory(data.getOne().getData().getSystemId(), categoryIdsCategoryQuote);
                loginServiceImpl.recacheLoginNode(loginNode);
            }

        }

        return data;
    }

    @Override
    public PdtableOne updatePdtable(RequestPdtableSave pdtableSave, SPdtable sPdtable) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        long id = pdtableSave.getId();
        long systemId = pdtableSave.getSystemId();
        short status = pdtableSave.getStatus();
        String content = pdtableSave.getContent();
        Date releasedAt = pdtableSave.getReleasedAt();
        List<PdtableTitleItem> titleItem = pdtableSave.getTitleItem();
        long imageRepertoryId = pdtableSave.getImageRepertoryId();
        RepertoryImgTagConfig repertoryImgTagConfig = pdtableSave.getImageRepertoryConfig();
        String imageRepertoryConfig = objectMapper.writeValueAsString(repertoryImgTagConfig);
        long fileRepertoryId = pdtableSave.getFileRepertoryId();
        String fileRepertoryConfig = pdtableSave.getFileRepertoryConfig();

        List<Long> categoryIds = pdtableSave.getCategoryIds();
        RequestItemSeo seo = pdtableSave.getSeo();
        SSeoItem sSeoItem = new SSeoItem();
        sSeoItem.setHostId(hostId).setSiteId(siteId).setSystemId(siteId).setItemId(-1L).setTitle(seo.getTitle()).setKeywords(seo.getKeywords())
                .setDescription(seo.getDescription());

        FeignUpdatePdtable updatePdtable = new FeignUpdatePdtable();
        updatePdtable.setId(id).setHostId(hostId).setSiteId(siteId).setSystemId(systemId).setStatus(status).setRefuse(sPdtable.getRefuse())
                .setTop(sPdtable.getTop()).setOrderNum(1).setContent(content).setReleasedAt(releasedAt).setTitleItem(titleItem)
                .setImageRepertoryId(imageRepertoryId).setImageRepertoryConfig(imageRepertoryConfig).setFileRepertoryId(fileRepertoryId)
                .setFileRepertoryConfig(fileRepertoryConfig).setCategoryIds(categoryIds).setSeo(sSeoItem);

        RestResult restResult = cPdtableFeign.updatePdtable(updatePdtable);
        PdtableOne data = RestResultUtil.data(restResult, PdtableOne.class);

        if (data != null) {
            ItemCustomLink customLink = pdtableSave.getItemCustomLink();
            if (customLink != null) {
                makeCustomLink(data, customLink);
            } else {
                // 删除动作
                systemItemCustomLinkServiceImpl.deleteByHostSiteSystemItemId(hostId, siteId, systemId, data.getOne().getData().getId());
            }
        }

        return data;
    }

    @Override
    public List<PdtableOne> deletePdtable(long systemId, List<Long> ids) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        FeignDeletePdtable deletePdtable = new FeignDeletePdtable();
        deletePdtable.setHostId(hostId).setSiteId(siteId).setSystemId(systemId).setIds(ids);
        RestResult restResult = cPdtableFeign.deletePdtable(deletePdtable);
        @SuppressWarnings("unchecked")
        List<PdtableOne> list = (ArrayList<PdtableOne>) RestResultUtil.data(restResult, new TypeReference<ArrayList<PdtableOne>>() {
        });

        return list;
    }

    @Override
    public List<PdtableOne> reductionPdtable(long systemId, List<Long> ids) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        FeignReductionPdtable reductionPdtable = new FeignReductionPdtable();
        reductionPdtable.setHostId(hostId).setSiteId(siteId).setSystemId(systemId).setIds(ids);

        RestResult restResult = cPdtableFeign.reductionPdtable(reductionPdtable);
        @SuppressWarnings("unchecked")
        List<PdtableOne> list = (ArrayList<PdtableOne>) RestResultUtil.data(restResult, new TypeReference<ArrayList<PdtableOne>>() {
        });

        return list;
    }

    @Override
    public List<PdtableOne> cleanPdtable(long systemId, List<Long> ids) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        FeignCleanPdtable cleanPdtable = new FeignCleanPdtable();
        cleanPdtable.setHostId(hostId).setSiteId(siteId).setSystemId(systemId).setIds(ids);

        RestResult restResult = cPdtableFeign.cleanPdtable(cleanPdtable);
        @SuppressWarnings("unchecked")
        List<PdtableOne> list = (ArrayList<PdtableOne>) RestResultUtil.data(restResult, new TypeReference<ArrayList<PdtableOne>>() {
        });

        return list;
    }

    @Override
    public void cleanAllPdtable(long systemId) {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();

        cPdtableFeign.cleanAllPdtable(hostId, siteId, systemId);
    }

    @Override
    public String excelDemoDownloadUrl(long systemId) throws Exception {
        Long hostId = requestHolder.getHost().getId();
        String url = "/api/download/pdtable/excel-demo/" + CryptoJava.en(String.valueOf(hostId)) + "/" + CryptoJava.en(String.valueOf(systemId));
        return url;
    }

    @Override
    public JsonResult excelImport(long repertoryId, long systemId) throws IOException {
        Host host = requestHolder.getHost();
        Long siteId = requestHolder.getCurrentSite().getId();
        return excelImport(host, siteId, repertoryId, systemId);
    }

    @Override
    public JsonResult excelImport(Host host, long siteId, long repertoryId, long systemId) throws IOException {
        Long hostId = host.getId();
        HRepertory hRepertory = repertoryServiceImpl.findByHostIdAndId(repertoryId, hostId);
        if (hRepertory == null) {
            return JsonResult.illegal();
        }

        String basePath = globalProperties.getSite().getBasePath();
        String userPathByCode = SitePathUtil.getUserPathByCode(basePath, host.getRandomCode());

        // 资源图片完整路径
        String filefullpath = userPathByCode + "/" + hRepertory.getFilepath();
        if (!FileUtil.isFile(filefullpath)) {
            return JsonResult.illegal();
        }

        String suffix = hRepertory.getSuffix();
        if (!suffix.equalsIgnoreCase("xlsx")) {
            return JsonResult.illegal();
        }

        List<SPdtableTitle> listSPdtableTitle = findSPdtableTitleByHostSiteSystemId(hostId, siteId, systemId);
        List<SPdtableTitle> collect = null;
        SPdtableTitle sPdtableTitleName = null;
        if (CollUtil.isNotEmpty(listSPdtableTitle)) {
            collect = listSPdtableTitle.stream().filter(item -> item.getType() != null && item.getType() == (short) 1).collect(Collectors.toList());
            Optional<SPdtableTitle> findFirst = listSPdtableTitle.stream().filter(item -> item.getType() != null && item.getType() == (short) 5).findFirst();
            if (findFirst.isPresent()) {
                sPdtableTitleName = findFirst.get();
            }
        }
        if (sPdtableTitleName == null) {
            return JsonResult.assistance();
        }

        // 导入过程中错误信息，如果存在错误信息，则返回提示错误内容。
        AtomicReference<String> errMsg = new AtomicReference<>();
        // 执行Excel转换成导入 listInsertPdtableListData 的数据
        List<InsertPdtableListData> listInsertPdtableListData = readImportExcelData(filefullpath, sPdtableTitleName, collect, errMsg, 2000);
        if (StrUtil.isNotBlank(errMsg.get())) {
            return JsonResult.messageError(errMsg.get());
        }

        if (CollUtil.isEmpty(listInsertPdtableListData)) {
            return JsonResult.messageError("没有需要导入的数据！");
        }

        // 新增的情况下判断数据是否超过可使用的数据条数
        int num = hSSystemDataNumServiceImpl.pdtableitemNum();
        int usedNum = hSSystemDataNumServiceImpl.usedPdtableitemNum();
        int size = listInsertPdtableListData.size();
        if ((usedNum + size) > (num * 1.2)) {
            return JsonResult.messageError("产品表格系统允许" + num + "条数据，已使用" + usedNum + "条数据，导入约" + size + "条数据，无法添加，请联系管理员！");
        }

        FeignInsertPdtableList insertPdtableList = new FeignInsertPdtableList();
        insertPdtableList.setHostId(hostId).setSiteId(siteId).setSystemId(systemId).setList(listInsertPdtableListData);
        RestResult restResult = cPdtableFeign.insertPdtableList(insertPdtableList);
        Integer count = RestResultUtil.data(restResult, Integer.class);

        return JsonResult.messageSuccess("成功导入" + count + "条数据！", count);
    }

    protected List<InsertPdtableListData> readImportExcelData(String filefullpath, SPdtableTitle sPdtableTitleName, List<SPdtableTitle> listSPdtableTitle,
                                                              AtomicReference<String> errMsg, int max) {
        if (sPdtableTitleName == null) {
            return null;
        }

        AtomicBoolean atomicRead = new AtomicBoolean();
        atomicRead.set(true);

        Map<Integer, SPdtableTitle> colIndexMap = new HashMap<>();
        AtomicReference<Map<Integer, SPdtableTitle>> atomicColIndexMap = new AtomicReference<>(colIndexMap);

        List<InsertPdtableListDataCategoryNames> listInsertPdtableListDataCategoryNames = new ArrayList<>();
        AtomicReference<List<InsertPdtableListDataCategoryNames>> atomicListInsertPdtableListDataCategoryNames = new AtomicReference<>(
                listInsertPdtableListDataCategoryNames);

        Long hostId = sPdtableTitleName.getHostId();
        Long siteId = sPdtableTitleName.getSiteId();
        Long systemId = sPdtableTitleName.getSystemId();

        ExcelUtil.readBySax(FileUtil.file(filefullpath), 0, (sheetIndex, rowIndex, rowCells) -> {
            if (CollUtil.size(atomicListInsertPdtableListDataCategoryNames.get()) > max) {
                errMsg.set("导入数据过多，最多只能导入" + max + "条数据。");
                return;
            }
            String nameTitle = null;
            String categoryNameTitle = null;
            String relAtTitle = null;
            String title = null;
            if (rowIndex == 0L) {
                for (int i = 0; i < rowCells.size(); i++) {
                    Object rowCellsObject = rowCells.get(i);
                    if (i == 0) {
                        nameTitle = StrUtil.trim(String.valueOf(rowCellsObject));
                    } else if (i == 1) {
                        categoryNameTitle = StrUtil.trim(String.valueOf(rowCellsObject));
                    } else if (i == 2) {
                        relAtTitle = StrUtil.trim(String.valueOf(rowCellsObject));
                    } else {
                        if (rowCellsObject == null) {
                            break;
                        }
                        String valueOf = String.valueOf(rowCellsObject);
                        if (StrUtil.isBlank(valueOf)) {
                            break;
                        }
                        title = StrUtil.trim(valueOf);
                        if (StrUtil.isBlank(title)) {
                            break;
                        }
                        if (CollUtil.isEmpty(listSPdtableTitle)) {
                            errMsg.set("Excel表中头部标题 " + title + " 未在表格系统中定义。");
                            atomicRead.set(false);
                            break;
                        }
                        AtomicReference<String> titleAtomic = new AtomicReference<>(title);
                        Optional<SPdtableTitle> optionalSPdtableTitle = listSPdtableTitle.stream().filter(item -> item.getTitle().equals(titleAtomic.get())).findFirst();
                        if (!optionalSPdtableTitle.isPresent()) {
                            errMsg.set("Excel表中头部标题 " + title + " 未在表格系统中定义其属性。");
                            atomicRead.set(false);
                            break;
                        }
                        // 表格头部标题对应的表格系统中定义的属性
                        Map<Integer, SPdtableTitle> map = atomicColIndexMap.get();
                        map.put(i, optionalSPdtableTitle.get());
                    }
                }

                if(StrUtil.isBlank(nameTitle) || StrUtil.isBlank(categoryNameTitle) || StrUtil.isBlank(relAtTitle) ){
                    errMsg.set("前三列系统固定字段异常，未能对应 名称、分类、发布时间 这三项。");
                    atomicRead.set(false);
                }else if ( !nameTitle.equals("名称") || !categoryNameTitle.equals("分类") || !relAtTitle.equals("发布时间")) {
                    errMsg.set("前三列系统固定字段异常，未能对应 名称、分类、发布时间 这三项。");
                    atomicRead.set(false);
                }
                return;
            }

            if (!atomicRead.get()) {
                return;
            }

            Date releasedAt = null;
            List<PdtableTitleItem> titleItem = new ArrayList<>();
            String categoryNamesString = null;
            for (int i = 0; i < rowCells.size(); i++) {
                Object rowCellsObject = rowCells.get(i);
                if (i == 0) {
                    if (rowCellsObject == null) {
                        break;
                    }
                    nameTitle = StrUtil.trim(String.valueOf(rowCellsObject));
                    if (StrUtil.isBlank(nameTitle)) {
                        break;
                    }
                    titleItem.add(new PdtableTitleItem(sPdtableTitleName.getId(), nameTitle));
                } else if (i == 1) {
                    if (rowCellsObject != null) {
                        String valueOf = String.valueOf(rowCellsObject);
                        if (StrUtil.isNotBlank(valueOf)) {
                            categoryNamesString = StrUtil.trim(valueOf);
                        }
                    }
                } else if (i == 2) {
                    relAtTitle = StrUtil.trim(String.valueOf(rowCellsObject));
                    if (StrUtil.isNotBlank(relAtTitle)) {
                        try {
                            releasedAt = DateUtil.parse(relAtTitle);
                        } catch (DateException e) {
                        }
                    }
                    if (releasedAt == null) {
                        releasedAt = DateUtil.date().toJdkDate();
                    }
                } else {
                    SPdtableTitle sPdtableTitle = atomicColIndexMap.get().get(i);
                    if (sPdtableTitle == null) {
                        break;
                    }
                    if (rowCellsObject == null) {
                        continue;
                    }
                    String valueOf = String.valueOf(rowCellsObject);
                    if (StrUtil.isBlank(valueOf)) {
                        continue;
                    }
                    title = StrUtil.trim(String.valueOf(rowCellsObject));
                    if (StrUtil.isBlank(title)) {
                        continue;
                    }
                    titleItem.add(new PdtableTitleItem(sPdtableTitle.getId(), title));
                }
            }

            if (CollUtil.isEmpty(titleItem)) {
                return;
            }

            InsertPdtableListData data = new InsertPdtableListData();
            data.setStatus((short) 1).setRefuse((short) 0).setTop((short) 0).setOrderNum(1).setContent("").setReleasedAt(releasedAt).setTitleItem(titleItem)
                    .setImageRepertoryId(-1L).setImageRepertoryConfig("").setFileRepertoryId(-1L).setFileRepertoryConfig("").setCategoryIds(null)
                    .setSeo(null);

            atomicListInsertPdtableListDataCategoryNames.get().add(new InsertPdtableListDataCategoryNames(data, categoryNamesString));
        });

        List<InsertPdtableListDataCategoryNames> readBySaxListInsertPdtableListDataCategoryNames = atomicListInsertPdtableListDataCategoryNames.get();
        if (CollUtil.isNotEmpty(readBySaxListInsertPdtableListDataCategoryNames)) {
            List<SCategories> listSCategories = null;
            try {
                listSCategories = categoryServiceImpl.getInfosByHostSiteSystemId(hostId, siteId, systemId);
            } catch (IOException e) {
            }
            if (CollUtil.isEmpty(listSCategories)) {
                listSCategories = new ArrayList<>();
            }

            for (InsertPdtableListDataCategoryNames insertPdtableListDataCategoryNames : readBySaxListInsertPdtableListDataCategoryNames) {
                InsertPdtableListData data = insertPdtableListDataCategoryNames.getData();

                String categoryNamesString = insertPdtableListDataCategoryNames.getCategoryNamesString();
                if (StrUtil.isBlank(categoryNamesString)) {
                    continue;
                }
                List<Long> categoryIds = new ArrayList<>();
                String[] split = categoryNamesString.split(",");
                if (ArrayUtil.isNotEmpty(split)) {
                    for (String sCategoriesString : split) {
                        if (StrUtil.isNotBlank(sCategoriesString)) {
                            if (CollUtil.isEmpty(listSCategories)) {
                                // 添加分类
                                SCategories sCategories = new SCategories();
                                sCategories.setId(null).setHostId(hostId).setSiteId(siteId).setSystemId(systemId).setParentId(0L).setName(sCategoriesString)
                                        .setRewrite("").setTarget("").setCount(0).setOrderNum(1);
                                SCategories insertSCategories = null;
                                try {
                                    insertSCategories = categoryServiceImpl.insertAppendOrderNum(sCategories);
                                } catch (IOException e) {
                                }
                                if (insertSCategories != null && insertSCategories.getId() != null) {
                                    categoryIds.add(insertSCategories.getId());
                                    listSCategories.add(insertSCategories);
                                }
                            } else {
                                Optional<SCategories> findFirst = listSCategories.stream().filter(item -> item.getName().equals(sCategoriesString)).findFirst();
                                if (findFirst.isPresent()) {
                                    categoryIds.add(findFirst.get().getId());
                                } else {
                                    // 添加分类
                                    SCategories sCategories = new SCategories();
                                    sCategories.setId(null).setHostId(hostId).setSiteId(siteId).setSystemId(systemId).setParentId(0L).setName(sCategoriesString)
                                            .setRewrite("").setTarget("").setCount(0).setOrderNum(1);
                                    SCategories insertSCategories = null;
                                    try {
                                        insertSCategories = categoryServiceImpl.insertAppendOrderNum(sCategories);
                                    } catch (IOException e) {
                                        log.error(e.getMessage());
                                    }
                                    if (insertSCategories != null && insertSCategories.getId() != null) {
                                        categoryIds.add(insertSCategories.getId());
                                        listSCategories.add(insertSCategories);
                                    }
                                }
                            }
                        }
                    }
                    data.setCategoryIds(categoryIds);
                }
            }
        }

        List<InsertPdtableListData> collect = readBySaxListInsertPdtableListDataCategoryNames.stream().map(InsertPdtableListDataCategoryNames::getData).collect(Collectors.toList());

        return collect;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class InsertPdtableListDataCategoryNames {
        InsertPdtableListData data = null;
        String categoryNamesString = null;
    }

    protected void makeCustomLink(PdtableOne data, ItemCustomLink customLink) throws IOException {
        if (data != null) {
            if (customLink != null) {
                if (data.getOne() != null) {
                    PdtableItem onePdtableItem = data.getOne();
                    if (onePdtableItem.getData() != null) {
                        SPdtable dataSPdtable = onePdtableItem.getData();
                        if (dataSPdtable.getId() != null) {
                            Long sPdtableId = dataSPdtable.getId();
                            short status = customLink.getStatus();
                            List<String> path = customLink.getPath();
                            List<String> collect = path.stream().filter(StrUtil::isNotBlank).collect(Collectors.toList());
                            JsonResult saveItemCustomLink = systemItemCustomLinkServiceImpl.saveItemCustomLink(dataSPdtable.getSystemId(), sPdtableId, status,
                                    CollUtil.join(collect, "/"), "");
                            if (saveItemCustomLink.getCode() == 200) {
                                makeCustomLink(data);
                            }
                        }
                    }
                }
            }
        }
    }

    protected void makeCustomLink(PdtableOne data) throws IOException {
        if (data != null) {
            if (data.getOne() != null) {
                PdtableItem onePdtableItem = data.getOne();
                if (onePdtableItem.getData() != null) {
                    SPdtable dataSPdtable = onePdtableItem.getData();
                    if (dataSPdtable.getId() != null) {
                        JsonResult itemCustomLink = systemItemCustomLinkServiceImpl.itemCustomLink(dataSPdtable.getSystemId(), dataSPdtable.getId());
                        if (itemCustomLink.getCode() == 200) {
                            Object dataObject = itemCustomLink.getData();
                            onePdtableItem.setCustomLink(dataObject);
                        }
                    }
                }
            }
        }
    }
}
